package com.logi.lpromis.exp.operate;

import com.logi.lpromis.exp.ExpBag;
import com.logi.lpromis.exp.ExpValue;
import com.logi.lpromis.exp.Expression;
import com.logi.lpromis.exp.interf.IExpression;
import com.logi.lpromis.exp.interf.IGetFunctionParam;
import com.logi.lpromis.exp.util.ExpressionUtil;
import com.logi.lpromis.exp.util.ExpressionUtil.DataType;
import com.logi.lpromis.exp.util.ExpressionUtil.OperateType;
import com.logi.lpromis.log.LogisLog;
import com.logi.lpromis.tool.buffer.ModuleDataSet;
import com.logichina.lpromis5.serialization.interf.ISerializableInput;
import com.logichina.lpromis5.serialization.interf.ISerializableOutput;

public class ExtendFuncOperate extends AbstractOperate
{
	/**
	 * 扩展函数接口 扩展接口的引用可以是指向一个内部处理为静态的业务管理类 但处理前必须通过回调接口获得业务数据集，把处理结果分别开来
	 */
	public IExpression m_extendExp = null;

	/**
	 * 业务包函数号
	 */
	public int m_extendFuncType = 0;

	public ExtendFuncOperate(){}
	
	public ExtendFuncOperate(String strOperate, int funcType, IExpression extendExp)
	{
		this.m_operateType = OperateType.ExtendFuncOperate;
		this.m_strOperate = strOperate;

		m_extendFuncType = funcType;
		m_extendExp = extendExp;
	}

	public ExpValue excute(ExpBag bag, ExpValue value, Expression exp) throws Exception
	{
		String m_strValue = null;
		Object m_objTag = null;
		boolean m_bFinish = false;
		int m_dataType = DataType.nullType;

		String strError = ExtendFunctionCalculate(bag, exp, value);
		if (!"".equals(strError))
		{
			// m_strValue = strError;
			// m_bFinish = false;
			throw new Exception(strError);
		}
		else
		{
			// ExpValue value = bag.getExpValue(exp.expID);
			if (value != null)
			{
				m_objTag = value.m_objTag;
				m_strValue = value.m_strValue;
				m_dataType = value.m_dataType;
				m_bFinish = true;
			}
			else
			{
				m_objTag = null;
				m_strValue = "";
				m_dataType = DataType.stringType;
				m_bFinish = true;
			}
		}
		value.setExpValue(m_bFinish, m_dataType, m_strValue, m_objTag);
		return value;
	}

	/**
	 * 扩展函数处理
	 * 
	 * @return
	 */
	public String ExtendFunctionCalculate(ExpBag bag, Expression exp, ExpValue value)
	{
		String strError = "";
		try
		{
			bag.getBackCall().addAnalyseMessage("开始扩展函数计算:" + bag.getExpression().m_strExp);
			// 条件检查
			if (m_extendExp == null)
			{
				strError = "没能获得扩展函数处理接口!";
				return strError;
			}
			if (m_extendFuncType == -1)
			{
				strError = "没能获得扩展函数的编号!";
				return strError;
			}
			String[] splitName = m_strOperate.split("\\.");
			if (splitName.length != 2)
			{
				strError = "业务扩展模块的函数(" + m_strOperate + ")不正确";
				return strError;
			}
			String strModuleName = splitName[0].toUpperCase();
			if (bag.getBackCall() == null)
			{
				strError = "未设置回调接口";
				return strError;
			}
			ModuleDataSet moduleData = bag.getBackCall().getModuleDataSet(strModuleName);
			if (moduleData == null)
			{
				moduleData = m_extendExp.initialModuleDataSet();
				if (moduleData == null)
				{
					strError = "业务包(" + strModuleName + ")初始化数据集失败";
					return strError;
				}
				bag.getBackCall().addModuleDataSet(strModuleName, moduleData);
			}
			// 使用扩展函数ID,调用计算接口,完成计算
			bag.setExtendFuncParam((IGetFunctionParam) exp);
			strError = m_extendExp.makeCalculateDisp(m_extendFuncType, moduleData, bag, value);
			bag.getBackCall().addAnalyseMessage("使用扩展函数:" + strError);
			return strError;
		}
		catch (Exception e)
		{
			return LogisLog.error(e);
		}
	}

	private static final byte PARAM_EXTENDEXP = 1;

	private static final byte PARAM_EXTENDFUNCTYPE = 2;

	@Override
	public void serialize(ISerializableOutput out)
	{
		out.writeByte(PARAM_EXTENDEXP);
		String packName = m_extendExp.getClass().getPackage().getName();
		packName = packName.substring(packName.lastIndexOf(".") + 1, packName.length());
		out.writeString(packName);

		out.writeByte(PARAM_EXTENDFUNCTYPE);
		out.writeInt(m_extendFuncType);

		out.writeByte(0);

		super.serialize(out);
	}

	@Override
	public void unserialize(ISerializableInput in)
	{
		byte paramType = in.readByte();
		while (paramType > 0)
		{
			switch (paramType)
			{
			case PARAM_EXTENDEXP:
			{
				String name = in.readString();
				m_extendExp = ExpressionUtil.getExtendExp(name);
				break;
			}
			case PARAM_EXTENDFUNCTYPE:
				m_extendFuncType = in.readInt();
				break;
			}
			paramType = in.readByte();
		}
		super.unserialize(in);
	}
}
